﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {

        //此处定义全局变量
        public Form1()
        {
            InitializeComponent();
        }

        private string sourceProgram;

        private int pointer; //读头

        private token currentToken;

        private identifierTable idenTable;

        private tempVariableTable tempVarTable; 

        private midCodeTable tacTable; //中间代码表

        private bool isDebug = false;

        private bool bugFlag;//11.22新增抛错功能


        private void print(string str) { listBox1.Items.Add(str); }
        private void debug(string str) { listBox2.Items.Add(str); }


        #region 词法分析
        // nextInput 词法分析程序
        private token nextInput()
        {
            string tmpWord = "";
            int state = 0;//自动机状态编号

            while (sourceProgram[pointer] != '#')
            {
                char symbol = sourceProgram[pointer];

                if (symbol == ' ')
                {
                    pointer++;
                    continue;
                }
                if (state == 0)
                {
                    if (symbol == '$')
                    {
                        state = 100;
                        tmpWord += symbol;
                        pointer++;
                        continue;

                    }
                    else if (symbol >= '0' && symbol <= '9')
                    {

                        state = 200;
                        tmpWord += symbol;
                        pointer++;
                        if (sourceProgram[pointer] == '#')
                        {

                            return new token("整数", tmpWord);
                        }
                        continue;

                    }
                    else if (symbol == ';')
                    {
                        state = 300;
                        tmpWord += symbol;
                        pointer++;
                        return new token("分号", tmpWord);

                    }
                    else if (symbol == 'i')
                    {
                        state = 400;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == 'b')
                    {
                        state = 500;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == ',')
                    {
                        state = 600;
                        tmpWord += symbol;
                        pointer++;
                        return new token("逗号", tmpWord);
                    }
                    else if (symbol == ':')
                    {
                        state = 700;
                        tmpWord += symbol;
                        pointer++;
                        if (sourceProgram[pointer] == '#')
                        {
                            return new token("冒号", tmpWord);
                        }
                        continue;
                    }
                    else if (symbol == 'o')
                    {
                        state = 800;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == 'n')
                    {
                        state = 900;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == 't')
                    {
                        state = 1000;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == 'f')
                    {
                        state = 1100;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == '(')
                    {
                        state = 1200;
                        tmpWord += symbol;
                        pointer++;
                        return new token("左括号", tmpWord);
                    }
                    else if (symbol == ')')
                    {
                        state = 1300;
                        tmpWord += symbol;
                        pointer++;
                        return new token("右括号", tmpWord);
                    }
                    else if (symbol == '<')
                    {
                        state = 1400;
                        tmpWord += symbol;
                        pointer++;
                        if (sourceProgram[pointer] == '#')
                        {
                            return new token("关系", tmpWord);
                        }

                        continue;
                    }
                    else if (symbol == '>')
                    {
                        state = 1410;
                        tmpWord += symbol;
                        pointer++;
                        if (sourceProgram[pointer] == '#')
                        {
                            return new token("关系", tmpWord);
                        }
                        continue;
                    }
                    else if (symbol == '=')
                    {
                        state = 1420;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == '*' || symbol == '/' || symbol == '%')
                    {
                        state = 1500;
                        tmpWord += symbol;
                        pointer++;
                        return new token("乘法", tmpWord);
                    }
                    else if (symbol == '+' || symbol == '-')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("加法", tmpWord);
                    }

                    else if (symbol == 'e')
                    {
                        state = 1700;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == '{')
                    {
                        state = 1800;
                        tmpWord += symbol;
                        pointer++;
                        return new token("begin", tmpWord);
                    }
                    else if (symbol == '}')
                    {
                        state = 1900;
                        tmpWord += symbol;
                        pointer++;
                        return new token("end", tmpWord);
                    }
                    else if (symbol == 's')
                    {
                        state = 2000;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == 'a')
                    {
                        state = 2100;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == '"')
                    {
                        state = 2300;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == 'w')
                    {
                        state = 2400;
                        tmpWord += symbol;
                        pointer++;
                        continue;

                    }

                    else if (symbol == 'ε')
                    {

                        state = 2400;
                        tmpWord += symbol;
                        pointer++;
                        return new token("ε", tmpWord);

                    }

                    else
                    {
                        pointer++;
                        return new token("error", $"状态{state}无法识别的符号");
                    }
                }

                if (state == 100)
                {
                    if (symbol >= 'a' && symbol <= 'z')
                    {
                        state = 101;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }


                }
                if (state == 101)
                {
                    if ((symbol >= 'a' && symbol <= 'z') || (symbol >= '0' && symbol <= '9'))
                    {
                        state = 101;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == '$')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("标识符", tmpWord);
                    }
                }

                if (state == 200)
                {
                    if (symbol >= '0' && symbol <= '9')
                    {
                        state = 200;
                        tmpWord += symbol;
                        pointer++;
                        if (sourceProgram[pointer] == '#')
                        {
                            return new token("整数", tmpWord);
                        }
                        continue;
                    }
                    else
                    {
                        return new token("整数", tmpWord);
                    }



                }


                if (state == 400)
                {
                    if (symbol == 'n')
                    {
                        state = 401;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == 'f')
                    {
                        state = 1600;
                        tmpWord += symbol;
                        pointer++;
                        return new token("if", tmpWord);
                    }

                }
                //int
                if (state == 401)
                {
                    if (symbol == 't')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("变量说明", tmpWord);
                    }
                }

                if (state == 500)
                {
                    if (symbol == 'o')
                    {
                        state = 501;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 501)
                {
                    if (symbol == 'o')
                    {
                        state = 502;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 502)
                {
                    if (symbol == 'l')
                    {
                        state = 503;
                        tmpWord += symbol;
                        pointer++;
                        return new token("变量说明", tmpWord);
                    }
                }

                if (state == 700)
                {
                    if (symbol == '=')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("赋值号", tmpWord);
                    }
                    else
                    {
                        return new token("冒号", tmpWord);
                    }
                }
                if (state == 800)
                {
                    if (symbol == 'r')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("or", tmpWord);
                    }
                }

                if (state == 900)
                {
                    if (symbol == 'o')
                    {
                        state = 901;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 901)
                {
                    if (symbol == 't')
                    {

                        tmpWord += symbol;
                        pointer++;
                        return new token("not", tmpWord);
                    }
                }

                if (state == 1000)
                {
                    if (symbol == 'r')
                    {
                        state = 1001;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 1001)
                {
                    if (symbol == 'u')
                    {
                        state = 1002;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 1002)
                {
                    if (symbol == 'e')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("true", tmpWord);
                    }
                }
                if (state == 1100)
                {
                    if (symbol == 'a')
                    {
                        state = 1101;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 1101)
                {
                    if (symbol == 'l')
                    {
                        state = 1102;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 1102)
                {
                    if (symbol == 's')
                    {
                        state = 1103;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 1103)
                {
                    if (symbol == 'e')
                    {

                        tmpWord += symbol;
                        pointer++;
                        return new token("false", tmpWord);
                    }
                }

                if (state == 1400)
                {
                    if (symbol == '>')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("关系", tmpWord);// <>
                    }
                    else if (symbol == '=')
                    {
                        tmpWord += symbol;

                        pointer++;
                        return new token("关系", tmpWord);// <=

                    }
                    else
                    {
                        return new token("关系", tmpWord);// <
                    }

                }
                if (state == 1410)
                {
                    if (symbol == '=')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("关系", tmpWord);//  >=
                    }
                    else
                    {
                        return new token("关系", tmpWord);//  >
                    }
                }
                if (state == 1420)
                {
                    if (symbol == '=')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("关系", tmpWord);// ==


                    }
                }

                if (state == 1700)
                {
                    if (symbol == 'l')
                    {
                        state = 1701;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }

                }
                if (state == 1701)
                {
                    if (symbol == 's')
                    {
                        state = 1702;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 1702)
                {
                    if (symbol == 'e')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("else", tmpWord);
                    }
                }



                //end
                if (state == 1700)
                {
                    if (symbol == 'n')
                    {
                        state = 1705;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }

                }
                if (state == 1702)
                {
                    if (symbol == 'd')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("end2", tmpWord);
                    }
                }

                //string
                if (state == 2000)
                {
                    if (symbol == 't')
                    {
                        state = 2001;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 2001)
                {
                    if (symbol == 'r')
                    {
                        state = 2002;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 2002)
                {
                    if (symbol == 'i')
                    {
                        state = 2003;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 2003)
                {
                    if (symbol == 'n')
                    {
                        state = 2004;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 2004)
                {
                    if (symbol == 'g')
                    {
                        state = 2005;
                        tmpWord += symbol;
                        pointer++;
                        return new token("变量说明", tmpWord);
                    }
                }

                if (state == 2100)
                {
                    if (symbol == 'n')
                    {
                        state = 2101;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 2101)
                {
                    if (symbol == 'd')
                    {
                        state = 2102;
                        tmpWord += symbol;
                        pointer++;
                        return new token("and", tmpWord);
                    }
                }

                //11.21 发现词法分析string有错误
                if (state == 2300)
                {
                    /*
                    if ((symbol >= 'a' && symbol <= 'z') || symbol == 'ε')
                    {
                        state = 2301;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == '"')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("字符串", tmpWord);
                    }*/

                    if ((symbol != '"'))
                    {
                        state = 2300;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("字符串", tmpWord);
                    }


                }
                if (state == 2301)
                {
                    if ((symbol >= 'a' && symbol <= 'z') || (symbol >= '0' && symbol <= '9'))
                    {
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                    else if (symbol == '"')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("字符串", tmpWord);
                    }
                }

                //while
                if (state == 2400)
                {
                    if (symbol == 'h')
                    {
                        state = 2401;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 2401)
                {
                    if (symbol == 'i')
                    {
                        state = 2402;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 2402)
                {
                    if (symbol == 'l')
                    {
                        state = 2403;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (state == 2403)
                {
                    if (symbol == 'e')
                    {

                        tmpWord += symbol;
                        pointer++;
                        return new token("while", tmpWord);
                    }
                }

                //and
                if (((state == 2501)))
                {
                    if (symbol == 'n')
                    {
                        state = 2502;
                        tmpWord += symbol;
                        pointer++;
                        continue;
                    }
                }
                if (((state == 2502)))
                {
                    if (symbol == 'd')
                    {
                        tmpWord += symbol;
                        pointer++;
                        return new token("and", tmpWord);
                    }
                }


                pointer++;
                debug("skipping " + symbol);

            }


            pointer++;


            return new token("#", "#");
        }

        public class token
        {
            public string type { set; get; }
            public string value { set; get; }

            public token(string type, string value)
            {
                this.type = type;
                this.value = value;
            }

            public override string ToString()
            {
                return $"({this.type},{this.value})";
            }
        }


        #endregion
        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            listBox2.Items.Clear();

            sourceProgram=textBox1.Text+"#";

            pointer = 0;
            
            currentToken=nextInput();
            print(currentToken.ToString());

            while (currentToken.value != "#"&&currentToken.type!="error")
            {
                currentToken = nextInput();
                print(currentToken.ToString());
            }

            print("词法分析结束"); 

        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }


        #region 语法分析
        private void button2_Click(object sender, EventArgs e)
        {
            isDebug = false;
            listBox1.Items.Clear ();
            listBox2.Items.Clear ();

            sourceProgram=textBox1.Text+"#";
            pointer = 0;
            currentToken=nextInput();
            print(currentToken.ToString());
            parseProgram();
        }

        private bool match(string expectedTokenType)
        {
            if (currentToken.type != expectedTokenType)
            {
                //match失败
                if (isDebug)
                    debug($"匹配失败：expect{expectedTokenType}.got{currentToken.type}");
                else
                    print($"匹配失败：expect{expectedTokenType}.got{currentToken.type}");
                return false;
            }
            if (isDebug)
                debug($"匹配成功：expect {expectedTokenType}");
            else
                print($"匹配成功：expect {expectedTokenType}");
            currentToken = nextInput();
            debug(currentToken.ToString());

            return true;
        }
        private void parseProgram()
        {
            print("推导：<程序> → <变量说明部分> <语句部分>");
            parseDeclareSection();
            parseStatementSection();

            print("语法分析结束。");
        }
        private void parseDeclareSection()
        {
            print("推导：<变量说明部分> →<变量说明语句> 分号 A");
            parseDeclareStatement();
            match("分号");
            parseA();
        }

        private void parseA()
        {
            print("选择产生式:A →<变量说明语句> 分号 A | ε ");

            if (currentToken.type == "变量说明")
            {
                print("推导：A →<变量说明语句> 分号 A ");
                parseDeclareStatement();
                match("分号");
                parseA();
            }
            else if (currentToken.type == "标识符"
                || currentToken.type == "if"
                || currentToken.type == "while")
            {
                print("推导：A → ε ");
            }
            else
            {
                print("A");
            }
        }
        private void parseDeclareStatement()
        {
            print("推导：<变量说明语句> → 变量说明 <标识符列表>  ");
            match("变量说明");
            parseVarList();
        }
        private void parseVarList()
        {
            print("推导：<标识符列表> →标识符 B");
            match("标识符");
            parseB();
        }
        private void parseB()
        {
            print("选择产生式:B →逗号 标识符 B | ε ");

            if (currentToken.type == "逗号")
            {
                print("推导：B →逗号 标识符 B  ");
                match("逗号");
                match("标识符");
                parseB();
            }
            else if (currentToken.type == "分号")
            {
                print("推导：B → ε ");
            }
            else
            {
                print("B");
            }
        }
        private void parseStatementSection()
        {
            print("推导：<语句部分> →<语句)> C");
            parseStatement();
            parseC();
        }
        private void parseC()
        {
            print("选择产生式:C → 分号 <语句> C | ε");
            if (currentToken.type == "分号")
            {
                print("推导：C → 分号 <语句> C  ");
                match("分号");
                parseStatement();
                parseC();
            }
            else if (currentToken.type == "#"
                || currentToken.type == "end")
            {
                print("推导：C → ε ");
            }
            else
            {
                print("C");
            }
        }
        private void parseStatement()
        {
            print("选择产生式:<语句> → <赋值语句>|<条件语句>|<循环语句>");
            if (currentToken.type == "标识符")
            {
                print("推导：<语句> → <赋值语句>");
                parseAssignmentStatement();
            }
            else if (currentToken.type == "if")
            {
                print("推导：<语句> → <条件语句>");
                parseConditionStatement();
            }
            else if (currentToken.type == "while")
            {
                print("推导：<语句> → <循环语句>");
                parseLoopStatement();
            }
            else
            {
                print("parseStatement");
            }
        }
        private void parseAssignmentStatement()
        {
            print("推导:<赋值语句> → 标识符 赋值号 <表达式>");
            match("标识符");
            match("赋值号");
            parseExpression();
        }
        private void parseExpression()
        {
            print("推导：<表达式> → < conjunction > D");
            parseConjunction();
            parseD();
        }
        private void parseD()
        {
            print("选择产生式：D → or < conjunction > D | ε");
            if (currentToken.type == "or")
            {
                print("推导：D → or < conjunction > D");
                match("or");
                parseConjunction();
                parseD();
            }
            //{分号，#，end，右括号
            else if (currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号")
            {
                print("推导：D →ε");
            }
            else
            {
                print("D");
            }
        }
        private void parseConjunction()
        {
            print("推导：< conjunction > → < inversion > E");
            parseInversion();
            parseE();
        }

        private void parseE()
        {
            print("选择产生式:E → and < inversion > E | ε");
            if (currentToken.type == "and")
            {
                print("推导：E → and < inversion > E");
                match("and");
                parseInversion();
                parseE();
            }
            else if (currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号")
            {
                print("推导：E → ε");
            }
            else
            {
                print("E");
            }
        }
        private void parseInversion()
        {
            print("选择产生式:< inversion > → not < inversion > | < 关系表达式 >");
            if (currentToken.type == "not")
            {
                print("推导:< inversion > → not < inversion >");
                match("not");
                parseInversion();
            }
            else if (currentToken.type == "标识符"
                || currentToken.type == "true"
                || currentToken.type == "false"
                || currentToken.type == "左括号"
                || currentToken.type == "字符串"
                || currentToken.type == "整数")
            {
                print("推导:< inversion > → < 关系表达式 >");
                parseRelationExpression();
            }
            else
            {
                print("parseInversion");
            }
        }
        private void parseRelationExpression()//关系表达式
        {
            print("推导:< 关系表达式 > → <算术表达式> F");
            parseArithmeticExpression();
            parseF();
        }
        private void parseF()
        {
            print("选择产生式:F → 关系运算符 <算术表达式> | ε");
            if (currentToken.type == "关系")
            {
                print("推导:F → 关系运算符 <算术表达式> ");
                match("关系");
                parseArithmeticExpression();
            }
            //{and，or，分号，#，end，右括号}
            else if (currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号"
                || currentToken.type == "and")
            {
                print("推导:F →ε");
            }
            else
            {
                print("F");
            }
        }
        private void parseArithmeticExpression()//算术表达式
        {
            print("推导:<算术表达式> → <term> G");
            parseTerm();
            parseG();
        }
        private void parseG()
        {
            print("选择产生式:G → 加法运算符 <term> G | ε");
            if (currentToken.type == "加法")
            {
                print("推导:G → 加法运算符 <term> G ");
                match("加法");

                parseTerm();
                parseG();
            }
            //{ and，or, 分号，#，end，右括号，关系运算符}
            else if (currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号"
                || currentToken.type == "and"
                || currentToken.type == "关系")
            {
                print("推导:G →ε");
            }
            else
            {
                print("G");
            }
        }
        private void parseTerm()
        {
            print("推导:<term> → <factor> H");
            parseFactor();
            parseH();
        }
        private void parseH()
        {
            print("选择产生式:H → 乘法运算符 <factor> H | ε");
            if (currentToken.type == "乘法")
            {
                print("推导:H → 乘法运算符 <factor> H ");
                match("乘法");
                parseFactor();
                parseH();
            }
            else if (currentToken.type == "加法"
                || currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号"
                || currentToken.type == "and"
                || currentToken.type == "关系")
            {
                print("推导:H →ε");
            }
            else
            {
                print("H");
            }
        }

        private void parseFactor()
        {
            print("选择产生式:<factor> → 标识符 | true | false | <字符串> | <整数数列> | 左括号 <表达式> 右括号");
            if (currentToken.type == "标识符")
            {
                print("推导：<factor> → 标识符 ");
                match("标识符");
            }
            else if (currentToken.type == "true")
            {
                print("推导：<factor> → true ");
                match("true");
            }
            else if (currentToken.type == "false")
            {
                print("推导：<factor> → false ");
                match("false");
            }
            else if (currentToken.type == "左引号" || currentToken.type == "字符串")
            {
                print("推导：<factor> → <字符串> ");
                parseStr();
            }
            else if (currentToken.type == "整数")
            {
                print("推导：<factor> → <整数数列> ");
                parseNumberList();
            }
            else if (currentToken.type == "左括号")
            {
                print("推导：<factor> → 左括号 <表达式> 右括号 ");
                match("左括号");
                parseExpression();
                match("右括号");
            }
            else
            {
                print("parseFactor");
            }

        }
        private void parseStr()
        {
            print("推导:<字符串> → 前引号 <字母序列> 后引号");
            match("左引号");
            parseSequence();
            match("右引号");
        }
        private void parseNumberList()//整数数列
        {
            print("推导:<整数数列> →数字 J");
            match("整数");
            parseJ();
        }

        private void parseJ()
        {
            print("选择产生式:J → 数字 J | ε");
            if (currentToken.type == "整数")
            {
                print("推导:J → 数字 J ");
                match("整数");
                parseJ();
            }
            else if (currentToken.type == "乘法"
                || currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号"
                || currentToken.type == "and"
                || currentToken.type == "关系")
            {
                print("推导:J → ε");
            }
            else
            {
                print("J");
            }
        }

        private void parseSequence()//字母序列
        {
            print("推导:<字母序列> →ε I");
            match("ε");
            parseI();
        }
        private void parseI()
        {
            print("选择产生式:I → 数字 I | 字母 I | ε");
            if (currentToken.type == "整数")
            {
                print("推导:I → 数字 I ");
                match("整数");
                parseI();
            }

            else if (currentToken.type == "字符串")
            {
                print("推导:I → 字母 I ");
                match("字符串");
                parseI();
            }
            else if (currentToken.type == "右引号")
            {
                print("推导:I → ε");
            }
            else
            {
                print("I");
            }
        }
        private void parseConditionStatement()
        {
            print("推导:<条件语句> → if 左括号 <表达式> 右括号 <嵌套语句> else <嵌套语句>");
            match("if");
            match("左括号");
            parseExpression();
            match("右括号");
            parseNestedStatement();
            match("else");
            parseNestedStatement();
        }
        private void parseLoopStatement()
        {
            print("推导:<循环语句> → while 左括号 <表达式> 右括号 冒号 <嵌套语句>");
            match("while");
            match("左括号");
            parseExpression();
            match("右括号");
            match("冒号");
            parseNestedStatement();
        }

        private void parseNestedStatement()
        {
            print("选择产生式:<嵌套语句> → <语句> 分号 |<复合语句>");
            if (currentToken.type == "if"
                || currentToken.type == "标识符"
                || currentToken.type == "while")
            {
                print("推导:<嵌套语句> → <语句> 分号 ");
                parseStatement();
                match("分号");
            }
            else if (currentToken.type == "begin")
            {
                print("推导:<嵌套语句> → <复合语句> ");
                parseComplexStatement();
            }
            else
            {
                print("parseNestedStatement");
            }
        }
        private void parseComplexStatement()
        {
            print("推导:<复合语句> → { <语句部分> }");
            match("begin");
            parseStatementSection();
            match("end");
        }



        #endregion


        #region 语义分析
        private void button3_Click(object sender, EventArgs e)
        {
            isDebug = true;
            listBox1.Items.Clear();
            listBox2.Items.Clear();

            sourceProgram = textBox1.Text + "#";
            pointer = 0;

            idenTable = new identifierTable();
            tempVarTable = new tempVariableTable();
            tacTable = new midCodeTable();


            //11.22测试编译器性能，增加时间测试函数
            DateTime startTime = DateTime.Now;
            currentToken = nextInput(); 
            debug(currentToken.ToString());

            translateTACProgram();
            tacTable.dump(listBox1);
            idenTable.dump(listBox2);
            DateTime endTime = DateTime.Now;
            TimeSpan ts = endTime - startTime;
            print("============运行时间============");
            print("运行时间："+ts.TotalMilliseconds.ToString());

            //tacTable.generate("declare", "int", "null", "$a$.type");
            //tacTable.generate("declare", "int", "null", "$b$.type");
            //tacTable.generate("declare", "int", "null", "$c$.type");
            //tacTable.dump(listBox1);

            //保存到txt文件内
            
              string path = Application.StartupPath + @"\outputTAC.txt";
              tacTable.saveToTXT(path);
            debug("=================运行日志=================");
            debug("文件路径为：");
              debug(path);
            

            // print(tempVarTable.createNewVariable().ToString());
            // print(tempVarTable.createNewVariable().ToString());
            // print(tempVarTable.createNewVariable().ToString());

            //identifierTable idenTable  = new identifierTable();
            //idenTable.Add("abc");
            //idenTable.Add("def");
            //idenTable.dump(listBox1);
            //currentToken = nextInput(); 
            //debug(currentToken.ToString());
            //translateTACProgram();
        }

        /*
        private void translateTACProgram()
        {
            debug("推导：<程序> → <变量说明部分> <语句部分>");
            translateTACDeclareSection();
            translateTACStatementSection();

            debug("语法分析结束。");
        }
        private void translateTACDeclareSection()
        {
            debug("推导：<变量说明部分> →<变量说明语句> 分号 A");
            translateTACDeclareStatement();
            match("分号");
            translateTACA();
        }

        private void translateTACA()
        {
            debug("选择产生式:A →<变量说明语句> 分号 A | ε ");

            if (currentToken.type == "变量说明")
            {
                debug("推导：A →<变量说明语句> 分号 A ");
                translateTACDeclareStatement();
                match("分号");
                translateTACA();
            }
            else if (currentToken.type == "标识符"
                || currentToken.type == "if"
                || currentToken.type == "while")
            {
                debug("推导：A → ε ");
            }
            else
            {
                debug("A");
            }
        }
        private void translateTACDeclareStatement()
        {
            debug("推导：<变量说明语句> → 变量说明 <标识符列表> ");
            match("变量说明");
            translateTACVarList();
        }
        private void translateTACVarList()
        {
            debug("推导：<标识符列表> →标识符 B");
            match("标识符");
            translateTACB();
        }
        private void translateTACB()
        {
            debug("选择产生式:B →逗号 标识符 B | ε ");

            if (currentToken.type == "逗号")
            {
                debug("推导：B →逗号 标识符 B  ");
                match("逗号");
                match("标识符");
                translateTACB();
            }
            else if (currentToken.type == "分号")
            {
                debug("推导：B → ε ");
            }
            else
            {
                debug("B");
            }
        }*/
        private void translateTACProgram()   //程序
        {
            debug("推导：<程序> -> <变量说明部分><语句部分>");
            translateTACDeclareSection();
            translateTACStatementSection();
        }

        private void translateTACDeclareSection() //变量说明部分
        {
            debug("推导：<变量说明部分> -> <变量说明语句> 分号 A");
            translateTACDeclareStatement();
            if (!match("分号")) { 
                return; 
                
            }
            translateTACA();
        }

        private void translateTACA()
        {
            debug("选择产生式：A -> <变量说明语句> 分号 A | ε");
            if (currentToken.type == "变量说明")
            {
                debug("推导：A -> <变量说明语句> 分号 A");
                translateTACDeclareStatement();
                //if (match("分号")) { return; }
                match("分号");
                translateTACA();

            }
            else if (currentToken.type == "标识符" || currentToken.type == "if"||currentToken.type =="while")
            {
                debug("推导：A -> ε");
            }

            //TODO:识别错误
        }

        private void translateTACDeclareStatement() //变量说明语句
        {
            debug("推导：<变量说明语句> -> 变量说明 <标识符列表>");

            string type = currentToken.value;
            match("变量说明");
            translateTACVarList(type);
        }

        private void translateTACVarList(string type)//标识符列表
        {
            debug("推导：<标识符列表> -> 标识符 B");

            string name = currentToken.value;
            match("标识符");

            // TODO: 语义检查
            idenTable.Add(name);
            idenTable.UpdateTypeByName(name, type);

            tacTable.generate("declare", type, "null", $"{name}.type");

            translateTACB(type);
        }

        private void translateTACB(string type)
        {
            debug("选择产生式：B ->逗号 标识符 B | ε");
            if (currentToken.type == "逗号")
            {
                debug("推导：B ->逗号 标识符 B");
                match("逗号");

                string name = currentToken.value;
                match("标识符");

                // TODO: 语义检查

                idenTable.Add(name);
                idenTable.UpdateTypeByName(name, type);

                tacTable.generate("declare", type, "null", $"{name}.type");

                translateTACB(type);

            }
            else if (currentToken.type == "分号")
            {
                debug("推导：B -> ε");
            }
        }
        private void translateTACStatementSection()
        {
            debug("推导：<语句部分> →<语句)> C");
            translateTACStatement();
            translateTACC();
        }
        private void translateTACC()
        {
            debug("选择产生式:C → 分号 <语句> C | ε");
            if (currentToken.type == "分号")
            {
                debug("推导：C → 分号 <语句> C  ");
                match("分号");
                translateTACStatement();
                translateTACC();
            }
            else if (currentToken.type == "#"
                || currentToken.type == "end")
            {
                debug("推导：C → ε ");
            }
            else
            {
                debug("C");
            }
        }
        private void translateTACStatement()
        {
            debug("选择产生式:<语句> → <赋值语句>|<条件语句>|<循环语句>");
            if (currentToken.type == "标识符")
            {
                debug("推导：<语句> → <赋值语句>");
                translateTACAssignmentStatement();
            }
            else if (currentToken.type == "if")
            {
                debug("推导：<语句> → <条件语句>");
                translateTACConditionStatement();
            }
            else if (currentToken.type == "while")
            {
                debug("推导：<语句> → <循环语句>");
                translateTACLoopStatement();
            }
            else
            {
                debug("translateTACStatement");
            }
        }
        private void translateTACAssignmentStatement()
        {
            debug("推导:<赋值语句> -> 标识符 赋值号 <表达式>");

            string name = currentToken.value;
            match("标识符");
            match("赋值号");
            triple Exp = translateTACExpression();

            //更新标识符列表
            //只有在动态编译才能获得正确结果
            //Exp = new triple("$abc$");
            //Exp.value = "123456789";
            if (Exp == null)
            {
                return ;
            }
            
            idenTable.UpdateValueByName(name, Exp.value);

            tacTable.generate("assign", Exp.name, "null",name);


        }
        private triple translateTACExpression()
        {
            debug("推导：<表达式> → < conjunction > D");
            triple E1 = translateTACConjunction();
            if(E1 == null)
            {
                print("Error: translateTACExpression 中 <conjunction>为空");
                return null;
            }
            triple E = translateTACD(E1);
           
            if(E == null)
            {
                print("Error: translateTACD 为空");
                return null;
            }

            return E;
        }
        private triple translateTACD(triple E1)
        {
            debug("选择产生式：D → or < conjunction > D | ε");
            if (currentToken.type == "or")
            {
                debug("推导：D → or < conjunction > D");
                match("or");

                triple E2 = translateTACConjunction();
                if (E2 == null)
                {
                    print("Error: translateTACD中conjunction为空 ");
                }

                //下面进行or运算

                //创建临时变量
                triple T = tempVarTable.createNewVariable();
                T.type = "bool";
                //根据E1和E2进行or运算，获得T的正确的值

                if(E1.value == "true" ||  E2.value == "true")
                {
                    T.value = "true";
                }
                else
                {
                    T.value = "false";
                }

               // T.value = "true";
                tacTable.generate("or", E1.name, E2.name, T.name);
                triple E = translateTACD(T);

                if (E == null) { print("Error: translateTACD中D为空值"); return null; }

                return E;
                //return translateTACD(T);
            }
            //{分号，#，end，右括号
            else if (currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号")
            {
                debug("推导：D →ε");
                return E1;
            }
            else
            {
                debug("D");
                //return null;
            }
            return null;

        }
        private triple translateTACConjunction()
        {
            debug("推导：< conjunction > → < inversion > E");

            triple E1 = translateTACInversion();
            if(E1 == null)
            {
                print("Error: translateTACInversion 中 <inversion>为空");
                return null;
            }
            triple E =  translateTACE(E1);
            if (E == null)
            {
                print("Error: translateTACE 中 <inversion>为空");
                return null;
            }
            return E;
        }

        private triple translateTACE(triple E1)
        {
            debug("选择产生式:E → and < inversion > E | ε");
            if (currentToken.type == "and")
            {
                debug("推导：E → and < inversion > E");
                match("and");
                
                triple E2 =  translateTACInversion();
                //创建临时变量
                triple T = tempVarTable.createNewVariable();
                T.type = "bool";
                if (E2 == null)
                {
                    print("Error: translateTACInversion中< inversion >为空");
                    return null;
                }

                //下面进行and运算 ---->要写
                //11.21实现and逻辑运算
                if(E1.value == "true" && E2.value == "false")
                {
                    T.value = "true";
                }else if(E1.value == "false" && E2.value == "true")
                {
                    T.value =  "true";
                }else if(E1.value == "true" && E2.value == "true")
                {
                    T.value = "false";
                }
                else
                {
                    T.value = "false";
                }


                
                
                tacTable.generate("and", E1.name, E2.name, T.name);
                return translateTACE(T);
            }
            else if (currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号")
            {
                debug("推导：E → ε");
                
                return E1;
            }
            else
            {
                debug("E");
                //return null;
            }
            return null;
        }



        private triple translateTACInversion()
        {
            debug("选择产生式:< inversion > → not < inversion > | < 关系表达式 >");
            if (currentToken.type == "not")
            {
                debug("推导:< inversion > → not < inversion >");
                match("not");

                triple E1 = translateTACInversion();
                //根据E1进行not运算，获得T的正确的值，  需要改进--->比如T为空的时候
                if (E1 == null)
                {
                    print("Error: translateTACInversion中< inversion >为空");
                    return null;
                }
                //创建临时变量
                triple T = tempVarTable.createNewVariable();
                T.type = "bool";
                
                T.value = (E1.value == "true") ? "true" : "false"; 
                tacTable.generate("not", E1.name, "null", T.name);
                return T;
            }
            else if (currentToken.type == "标识符"
                || currentToken.type == "true"
                || currentToken.type == "false"
                || currentToken.type == "左括号"
                || currentToken.type == "字符串"
                || currentToken.type == "整数")
            {
                debug("推导:< inversion > → < 关系表达式 >");

                triple E = translateTACRelationExpression();
                if(E == null)
                {
                    print("Error: translateTACRelationExpression 中 E为空");
                }
                return E;
            }
            else
            {
                debug("translateTACInversion");
               
            }
            return null;
            
        }


        private triple translateTACRelationExpression()//关系表达式
        {
            debug("推导:< 关系表达式 > → <算术表达式> F");
            triple E1 = translateTACArithmeticExpression();
            if (E1 == null)
            {
                print("Error: translateTACArithmeticExpression 为空");
                return null;
            }
            triple E = translateTACF(E1);
            if (E == null)
            {
                print("Error: translateTACRelationExpression 中 F为空");
                return null;
            }
            

            return E;
        }



        private triple translateTACF(triple E1)
        {
            debug("选择产生式:F → 关系运算符 <算术表达式> | ε");
            if (currentToken.type == "关系")
            {
                debug("推导:F → 关系运算符 <算术表达式> ");
                string op = currentToken.value;
                match("关系");
                triple E2 =  translateTACArithmeticExpression();

                //创建临时变量
                triple T = tempVarTable.createNewVariable();
                T.type = "bool";
                //根据E1和E2进行关系运算，获得T的正确的值


                if (E1 == null)
                {
                    print("Error:运算存在空值，请重新检查");
                    tacTable.generate(op, "null", E2.name, T.name);
                    return T;
                }

                else if (E2 == null)
                {
                    print("Error:运算存在空值，请重新检查");
                    tacTable.generate(op, E1.name, "null", T.name);
                    return T;
                }

                else
                {
                    //11.21添加关系运算符
                    if (op == "<")
                    {
                        op = "lt";

                        if (E1.type == "bool" && E2.type == "bool")
                        {
                            if (E1.value == "true" && E2.value == "true")
                            {
                                T.value = "false";
                            }
                            else if (E1.value == "false" && E2.value == "false")
                            {
                                T.value = "false";
                            }
                            else if (E1.value == "true" && E2.value == "false")
                            {
                                T.value = "false";
                            }
                            else if (E1.value == "false" && E2.value == "true")
                            {
                                T.value = "true";
                            }
                        }
                        else if (E1.type == "int" && E2.type == "int")
                        {
                            int num1, num2;
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num1 = Convert.ToInt32(E1.value);
                            num2 = Convert.ToInt32(E2.value);
                            if (num1 < num2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                        else if (E1.type == "string" && E2.type == "string")
                        {
                            string str1 = E1.value.ToString().Trim();
                            string str2 = E2.value.ToString().Trim();
                            int len1 = str1.Length;
                            int len2 = str2.Length;
                            if (len1 < len2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                    }
                    else if (op == ">")
                    {
                        op = "gt";
                        if (E1.type == "bool" && E2.type == "bool")
                        {
                            if (E1.value == "true" && E2.value == "false")
                            {
                                T.value = "true";
                            }
                            else { T.value = "false"; }

                        }
                        else if (E1.type == "int" && E2.type == "int")
                        {
                            int num1, num2;
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num1 = Convert.ToInt32(E1.value);
                            num2 = Convert.ToInt32(E2.value);
                            if (num1 > num2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                        else if (E1.type == "string" && E2.type == "string")
                        {
                            string str1 = E1.value.ToString().Trim();
                            string str2 = E2.value.ToString().Trim();
                            int len1 = str1.Length;
                            int len2 = str2.Length;
                            if (len1 > len2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                    }

                    else if (op == "<>")
                    {
                        op = "noteq";

                        if (E1.type == "bool" && E2.type == "bool")
                        {
                            if (E1.value != E2.value)
                            {
                                T.value = "true";
                            }
                            else { T.value = "false"; }

                        }
                        else if (E1.type == "int" && E2.type == "int")
                        {
                            int num1, num2;
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num1 = Convert.ToInt32(E1.value);
                            num2 = Convert.ToInt32(E2.value);
                            if (num1 != num2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                        else if (E1.type == "string" && E2.type == "string")
                        {
                            string str1 = E1.value.ToString().Trim();
                            string str2 = E2.value.ToString().Trim();
                            int len1 = str1.Length;
                            int len2 = str2.Length;
                            if (len1 != len2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                    }
                    else if ((op == "<="))
                    {
                        op = "lte";

                        if (E1.type == "bool" && E2.type == "bool")
                        {
                            if (E1.value == "true" && E2.value == "false")
                            {
                                T.value = "false";
                            }
                            else { T.value = "true"; }

                        }

                        else if (E1.type == "int" && E2.type == "int")
                        {
                            int num1, num2;
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num1 = Convert.ToInt32(E1.value);
                            num2 = Convert.ToInt32(E2.value);
                            if (num1 <= num2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                        else if (E1.type == "string" && E2.type == "string")
                        {
                            string str1 = E1.value.ToString().Trim();
                            string str2 = E2.value.ToString().Trim();
                            int len1 = str1.Length;
                            int len2 = str2.Length;
                            if (len1 <= len2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }

                    }
                    else if ((op == ">="))
                    {
                        op = "gte";

                        if (E1.type == "bool" && E2.type == "bool")
                        {
                            if (E1.value == "false" && E2.value == "true")
                            {
                                T.value = "false";
                            }
                            else { T.value = "true"; }

                        }
                        else if (E1.type == "int" && E2.type == "int")
                        {
                            int num1, num2;
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num1 = Convert.ToInt32(E1.value);
                            num2 = Convert.ToInt32(E2.value);
                            if (num1 >= num2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                        else if (E1.type == "string" && E2.type == "string")
                        {
                            string str1 = E1.value.ToString().Trim();
                            string str2 = E2.value.ToString().Trim();
                            int len1 = str1.Length;
                            int len2 = str2.Length;
                            if (len1 >= len2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }


                    }
                    else if ((op == "=="))
                    {
                        op = "eq";

                        if (E1.type == "bool" && E2.type == "bool")
                        {
                            if (E1.value == E2.value)
                            {
                                T.value = "true";
                            }
                            else { T.value = "false"; }

                        }
                        else if (E1.type == "int" && E2.type == "int")
                        {
                            int num1, num2;
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num1 = Convert.ToInt32(E1.value);
                            num2 = Convert.ToInt32(E2.value);
                            if (num1 == num2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                        else if (E1.type == "string" && E2.type == "string")
                        {
                            string str1 = E1.value.ToString().Trim();
                            string str2 = E2.value.ToString().Trim();
                            int len1 = str1.Length;
                            int len2 = str2.Length;
                            if (len1 == len2)
                            {
                                T.value = "true";
                            }
                            else
                            {
                                T.value = "false";
                            }
                        }
                    }

                    tacTable.generate(op, E1.name, E2.name, T.name);
                    return T;

                }

               /* else
                {
                    tacTable.generate(op, E1.name, E2.name, T.name);
                    return T;
                }*/

            }
            //{and，or，分号，#，end，右括号}
            else if (currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号"
                || currentToken.type == "and")
            {
                debug("推导:F →ε");
                return E1; 
            }
            else
            {
                debug("F");
               // return null;
            }
            return null;
           
        }


        private triple translateTACArithmeticExpression()//算术表达式
        {
            debug("推导:<算术表达式> → <term> G");
            triple E1 =  translateTACTerm();
            if(E1 == null)
            {
                print("Error: translateTACArithmeticExpression中Term 为空");
                return null;
            }
            triple E =  translateTACG(E1);
            if (E == null)
            {
                print("Error: translateTACArithmeticExpression中G 为空");
                return null;
            }
            return E;
        }


        private triple translateTACG(triple E1)
        {
            debug("选择产生式:G → 加法运算符 <term> G | ε");
            if (currentToken.type == "加法")
            {
                debug("推导:G → 加法运算符 <term> G ");
                string op = currentToken.value;
                match("加法");
                triple E2 =  translateTACTerm();
                if (E2 == null)
                {
                    print("Error: translateTACTerm E2");
                    return null;
                }
                //下面进行加法运算和减法运算
                //创建临时变量
                triple T = tempVarTable.createNewVariable();
                //**********************************************需要支持int和string*******************************************************//
                //11.21新增int类型和string类型的加减法


                //T.type = "int";
                //T.value = "1";

                if(op == "+") { 
                    op = "add";
                    if (E1.type == "string" && E2.type == "string")
                    {
                        T.type = "string";
                        if (op == "+")
                            T.value = E1.value + E2.value;
                    }
                    else
                    {
                        if (E1.type == "bool")
                        {
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                        }
                        if (E2.type == "bool")
                        {
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                        }

                        T.type = "int";
                        if (E1.value == "true") E1.value = "1";
                        if (E1.value == "false") E1.value = "0";
                        if (E2.value == "true") E2.value = "1";
                        if (E2.value == "false") E2.value = "0";
                        int T1 = Convert.ToInt32(E1.value);
                        //string T1 = E1.value.ToString();
                        int T2 = Convert.ToInt32(E2.value);
                        //string T2 = E2.value.ToString();

                        //计算T的值 
                        T.value = (T1 + T2).ToString();
                    }
                }
                else if(op == "-") { 
                    op = "sub";
                    if (E1.type == "bool")
                    {
                        if (E1.value == "true") E1.value = "1";
                        if (E1.value == "false") E1.value = "0";
                    }
                    if (E2.type == "bool")
                    {
                        if (E2.value == "true") E2.value = "1";
                        if (E2.value == "false") E2.value = "0";
                    }

                    T.type = "int";
                  
                    int T1 = Convert.ToInt32(E1.value);
                    int T2 = Convert.ToInt32(E2.value);

                    //计算T的值 
                   
                       // T.value = (T1 - T2).ToString();
                    if(T1-T2 < 0){
                       
                        T.value = "0";
                    }
                    else
                    {
                      
                        T.value = (T1 - T2).ToString();
                    }
                }

                tacTable.generate(op,E1.name,E2.name,T.name);
                return translateTACG(T);
            }
            //{ and，or, 分号，#，end，右括号，关系运算符}
            else if (currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号"
                || currentToken.type == "and"
                || currentToken.type == "关系")
            {
                debug("推导:G →ε");
                return E1;
            }
            else
            {
                debug("G");
                return null;
            }
            //return null;
        }




        private triple translateTACTerm()
        {
            debug("推导:<term> → <factor> H");

            triple E1 = translateTACFactor();

            if(E1 == null)
            {
                print("Error: translateTACFactor 中 E1为空");
                return null;
            }

            triple E =  translateTACH(E1);
            if(E == null)
            {
                print("Error: translateTACH中E为空");
                return null;
            }
            return E; 
        }




        //11.21此处存在异常空值
        //11.22已解决空值异常
        private triple translateTACH(triple E1)
        {
            debug("选择产生式:H → 乘法运算符 <factor> H | ε");
            
            if (currentToken.type == "乘法")
            {
                debug("推导:H → 乘法运算符 <factor> H ");
                string op = currentToken.value;
                match("乘法");
                triple E2 =  translateTACFactor();
                if (E2 == null)
                {
                    print("Error: translateTACFactor 为空");
                    return null;
                }

                //下面进行乘法运算
                triple T = tempVarTable.createNewVariable();

                if (op == "*")
                {
                    op = "mul";
                    if (E1.type == "int" && E2.type == "int" ||
                        E1.type == "int" && E2.type == "bool" ||
                        E1.type == "bool" && E2.type == "int" ||
                        E1.type == "bool" && E2.type == "bool")
                    {
                        T.type = "int";

                        int num1; int num2;
                        if (E1.type == "bool")
                        {
                            if (E1.value == "true") { num1 = 1; }
                            else { num1 = 0; }
                        }
                        else {
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num1 = Convert.ToInt32(E1.value); 
                        }

                        if (E2.type == "bool")
                        {
                            if (E2.value == "true") { num2 = 1; }
                            else { num2 = 0; }
                        }
                        else {
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num2 = Convert.ToInt32(E2.value); }

                        int num = num1 * num2;
                        if (num.ToString().Length > 4)
                            T.value = num.ToString().Substring(0, 4);
                        else
                            T.value = num.ToString();
                    }
                    else if (E1.type == "string" && (E2.type == "int" || E2.type == "bool"))
                    {
                        T.type = "string";
                        if (E1.value == "true") E1.value = "1";
                        if (E1.value == "false") E1.value = "0";
                        if (E2.value == "true") E2.value = "1";
                        if (E2.value == "false") E2.value = "0";
                        if (E2.value == "0" || E2.value == "false")
                            T.value = "";
                        else if (E2.value == "1" || E2.value == "true")
                            T.value = E1.value;
                        else if (E2.value == "2" || Convert.ToInt32(E2.value) > 2)
                        {
                            T.value = E1.value.Substring(0, E1.value.Length - 1) + E1.value.Substring(1, E1.value.Length - 1);
                        }
                        else
                        {
                            print($"Error: E1={E1.value} , E2={E2.value} 不支持‘*’的字符串重复运算");
                            return null;
                        }

                    }
                    else if ((E1.type == "int" || E1.type == "bool") && E2.type == "string")
                    {
                        T.type = "string";
                        if (E1.value == "true") E1.value = "1";
                        if (E1.value == "false") E1.value = "0";
                        if (E2.value == "true") E2.value = "1";
                        if (E2.value == "false") E2.value = "0";

                        if (E1.value == "0" || E1.value == "false")
                            T.value = "";
                        else if (E1.value == "1" || E1.value == "true")
                            T.value = E2.value;
                        else if (E1.value == "2" || Convert.ToInt32(E1.value) > 2)
                        {
                            T.value = E2.value.Substring(0, E2.value.Length - 1) + E2.value.Substring(1, E2.value.Length - 1);
                        }
                        else
                        {
                            print($"Error: E1={E1.value} , E2={E2.value} 不支持‘*’的字符串重复运算");
                            return null;
                        }

                    }
                    else
                    {
                        print($"Error: E1.{E1.type} , E2.{E2.type} 不支持‘*’运算");
                        return null;
                    }

                }
                else if (op == "/")
                {
                    op = "div";
                    T.type = "int";
                    if (E1.type == "int" && E2.type == "int" ||
                       E1.type == "int" && E2.type == "bool" ||
                       E1.type == "bool" && E2.type == "int" ||
                       E1.type == "bool" && E2.type == "bool")
                    {
                        T.type = "int";

                        int num1; int num2;
                        if (E1.type == "bool")
                        {
                            if (E1.value == "true") { num1 = 1; }
                            else { num1 = 0; }
                        }
                        else {
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num1 = Convert.ToInt32(E1.value); }

                        if (E2.type == "bool")
                        {
                            if (E2.value == "true") { num2 = 1; }
                            else { num2 = 0; }
                        }
                        else {
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num2 = Convert.ToInt32(E2.value); }

                        if (num2 == 0)
                        {
                            print("Error: div操作的除数不能为0");
                            return null;
                        }
                        T.value = (num1 / num2).ToString();
                    }
                    else
                    {
                        print($"Error: E1.{E1.type} , E2.{E2.type} 不支持‘/’运算");
                        return null;
                    }

                }
                else if (op == "%")
                {
                    op = "mod";
                    T.type = "int";
                    /*if (E1.type == "int" && E2.type == "int")
                    {
                        if (E2.value == "0")
                        {
                            print("mod操作的除数不能为0");
                            return null;
                        }
                        T.value = (Convert.ToInt32(E1.value) % Convert.ToInt32(E2.value)).ToString();
                    }*/

                    //11.21重新重构此分支
                    if (E1.type == "int" && E2.type == "int" ||E1.type == "int" && E2.type == "bool" ||
                        E1.type == "bool" && E2.type == "int" ||
                        E1.type == "bool" && E2.type == "bool")
                    {
                        T.type = "int";

                        int num1; int num2;
                        if (E1.type == "bool")
                        {
                            if (E1.value == "true") { num1 = 1; }
                            else { num1 = 0; }
                        }
                        else {
                            if (E1.value == "true") E1.value = "1";
                            if (E1.value == "false") E1.value = "0";
                            if (E2.value == "true") E2.value = "1";
                            if (E2.value == "false") E2.value = "0";
                            num1 = Convert.ToInt32(E1.value); }

                        if (E2.type == "bool")
                        {
                            if (E2.value == "true") { num2 = 1; }
                            else { num2 = 0; }
                        }
                        else {
                          //  print(E2.type.ToString());
                          //  print(E2.value);
                            //11.21这边存在类型异常问题
                            //11.23已解决
                            //if (E1.value == "true") E1.value = "1";
                           // if (E1.value == "false") E1.value = "0";
                           // if (E2.value == "true") E2.value = "1";
                            //if (E2.value == "false") E2.value = "0";
                            num2 = Convert.ToInt32(E2.value); 
                        }

                        if (num2 == 0)
                        {
                            print("Error: mod操作的除数不能为0");
                            return null;
                        }
                        T.value = (num1 % num2).ToString();
                    }



                    else
                    {
                        print($"Error: E1.{E1.type} , E2.{E2.type} 不支持‘%’运算");
                        return null;
                    }
                }

                tacTable.generate(op,E1.name,E2.name,T.name);
                //print("选择了乘法产生式");
                return translateTACH(T);
            }
            else if (currentToken.type == "加法"
                || currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号"
                || currentToken.type == "and"
                || currentToken.type == "关系")
            {
                debug("推导:H →ε");
                return E1;
            }
            else
            {
                debug("H");
                //return null;
            }
            return null;
        }

        private triple translateTACFactor()
        {
            debug("选择产生式:<factor> → 标识符 | true | false |字符串 | 左括号 <表达式> 右括号");
            if (currentToken.type == "标识符")
            {
                debug("推导：<factor> → 标识符 ");
                string name = currentToken.value;
                match("标识符");
                
                return idenTable.getIdentifierByName(name);

            }
            else if (currentToken.type == "true")
            {
                debug("推导：<factor> → true ");
                match("true");
                triple t = new triple("true");
                t.type = "bool";
                t.value = "true";

                return t;
            }
            else if (currentToken.type == "false")
            {
                debug("推导：<factor> → false ");
                match("false");

                triple t = new triple("false");
                t.type = "bool";
                t.value = "false";
                return t;

            }
            
            else if (currentToken.type == "字符串")
            {
                debug("推导：<factor> → <字符串> ");
                string value = currentToken.value;
                match("字符串");//11.21日，添加一个缺少的match()
                triple t = new triple(value);
                t.type = "string";
                t.value = value;
               // print(value);
                //translateTACStr();
                return t;
            }

            else if (currentToken.type == "整数")
            {
                debug("推导：<factor> → 整数 ");
                
                string value = currentToken.value;
                match("整数");

                triple t = new triple(value);
                //11.23 解决类型问题
                t.type = "int";
                //print(t.type);
                t.value = value;
                //print(t.value);
                return t;
                
                //translateTACNumberList();
            }
            else if (currentToken.type == "左括号")
            {
                debug("推导：<factor> → 左括号 <表达式> 右括号 ");
                match("左括号");
                //translateTACExpression();
                triple Exp = translateTACExpression();
                match("右括号");
                return Exp;
            }
            else
            {
                debug("translateTACFactor");
                return null;
            }
        
        }
        /*
        private void translateTACStr()
        {
            debug("推导:<字符串> → 前引号 <字母序列> 后引号");
            match("左引号");
            //translateTACSequence();
            match("右引号");
        }
        private void translateTACNumberList()//整数数列
        {
            debug("推导:<整数数列> →数字 J");
            match("整数");
            translateTACJ();
        }

        private void translateTACJ()
        {
            debug("选择产生式:J → 数字 J | ε");
            if (currentToken.type == "整数")
            {
                debug("推导:J → 数字 J ");
                match("整数");
                translateTACJ();
            }
            else if (currentToken.type == "乘法"
                || currentToken.type == "or"
                || currentToken.type == "分号"
                || currentToken.type == "#"
                || currentToken.type == "end"
                || currentToken.type == "右括号"
                || currentToken.type == "and"
                || currentToken.type == "关系")
            {
                debug("推导:J → ε");
            }
            else
            {
                debug("J");
            }
        }

        private void translateTACSequence()//字母序列
        {
            debug("推导:<字母序列> →ε I");
            match("ε");
            //translateTACI();
        }
        private void translateTACI()
        {
            debug("选择产生式:I → 数字 I | 字母 I | ε");
            if (currentToken.type == "整数")
            {
                debug("推导:I → 数字 I ");
                match("整数");
                //translateTACI();
            }

            else if (currentToken.type == "字符串")
            {
                debug("推导:I → 字母 I ");
                match("字符串");
                //translateTACI();
            }
            else if (currentToken.type == "右引号")
            {
                debug("推导:I → ε");
            }
            else
            {
                debug("I");
            }
        }*/
        private void translateTACConditionStatement()
        {
            debug("推导 : <条件语句> → if 左括号<表达式>右括号<嵌套语句> else <嵌套语句>");
            match("if");
            match("左括号");
            triple T = translateTACExpression();
            if (T == null)
            {
                print("<条件语句> → ...语句中，<表达式>为空");
                //bug = true;
                return;
            }


            tacTable.generate("jnz", T.name, "null", (tacTable.NXQ + 2).ToString());
            int falseIndex = tacTable.NXQ;
            tacTable.generate("jump", "null", "null", "0");

            match("右括号");
            translateTACNestedStatement();
           // if (bug) return;

            int exitIndex = tacTable.NXQ;
            tacTable.generate("jump", "null", "null", "0");
            tacTable.backpatch(falseIndex, (tacTable.NXQ).ToString());


            match("else");
            translateTACNestedStatement();
            //if (bug) return;

            tacTable.backpatch(exitIndex, (tacTable.NXQ).ToString());
        }
        private void translateTACLoopStatement()
        {
            debug("推导 : <cirState> → while 左括号<exp>右括号 冒号 <nesState>");
            match("while");
            match("左括号");

            int NEXT = tacTable.NXQ;
            triple E = translateTACExpression();
            if (E == null)
            {
                print("<cirState> → ...语句中，<exp>为空");
                //bug = true;
                return;
            }
            tacTable.generate("jnz", E.name, "null", (tacTable.NXQ + 2).ToString());
            int falseIndex = tacTable.NXQ;
            tacTable.generate("jump", "null", "null", "0");

            match("右括号");
            match("冒号");

            translateTACNestedStatement();
            //if (bug) return;

            tacTable.generate("jump", "null", "null", NEXT.ToString());
            tacTable.backpatch(falseIndex, (tacTable.NXQ).ToString());
        }

        private void translateTACNestedStatement()
        {
            debug("选择产生式 : <nesState> → <state>分号 |<compState>");
            if (currentToken.type == "标识符" ||
                currentToken.type == "if" ||
                currentToken.type == "while")
            {
                debug("推导 : <nesState> → <state>分号 ");
                translateTACStatement();
                //if (bug) return;
                match("分号");
            }
            else if (currentToken.type == "begin")
            {
                debug("推导 : <nesState> → <compState>");
                translateTACComplexStatement();
               // if (bug) return;
            }
            else
            {
                print("Error: when parseNestedState, the following input do not match the rule");
            }
        }
        private void translateTACComplexStatement()
        {
            debug("推导 : <compState> → begin <stateSec> end");
            match("begin");
            translateTACStatementSection();
            //if (bug) return;
            match("end");
        }

        public class triple
        {
            public string name { set; get; }
            public string type { set; get; }
            public string value { set; get; }

            public triple(string name)
            {
                this.name = name;
                this.type = "";
                this.value = "";
            }

            public override string ToString()
            {
               // return $"{this.type}| \t {this.type}| \t{this.name}";
                return  $"{this.type,-10}|{this.value,-10}|{this.name,-10}";
            }

            public int getValueAsInt32()
            {
                if(this.value == "")return -1;
                if(this.type != "int") return -1;
                return  Convert.ToInt32(this.value);
            }

            public bool getValueAsBOOL()
            {
                if (this.type != "bool") return false; 
                if(this.value =="") return false;
                if (this.value == "true") return true;
                return false;
            }
        }

        //四元式的定义
        public class TAC
        {
            //操作符
            public string op { set; get; } 
            //左操作数
            public string oprand1 { set; get; }

            //右操作数
            public string oprand2 { set; get; }

            //结果
            public string result { set; get; }

            public TAC(string op,string oprand1,string oprand2,string result)
            {
                this.op = op ;
                this.oprand1 = oprand1 ;
                this.oprand2 = oprand2 ; 
                this.result = result ;
            }

            public override string ToString()
            {
                return $"({this.op,-8},{this.oprand1,-8},{this.oprand2,-8},{this.result,-8})";
            }
        }


        //中间代码表
        private class midCodeTable
        {
            public List<TAC> table = new List<TAC>();
            public int NXQ { get { return table.Count; } }

            public midCodeTable()
            {
                this.table.Clear(); 
            }

            public void generate(string op, string oprand1, string oprand2, string result)
            {
                this.table.Add(new TAC(op,oprand1,oprand2,result));
            }

            public void backpatch(int index,string result)
            {
                if(index >= table.Count) return;
                this.table[index].result = result ;
            }

            public void dump(ListBox lb)
            {
                lb.Items.Add($"============ 编译器，启动！==============");
               
              
                lb.Items.Add($"中间代码表如下：");
                //lb.Items.Add($"|name----|type----|value");
                lb.Items.Add($"   {"op",-8} {"oprand1",-8} {"oprand2",-8} {"result",-8}");
                for (int i = 0; i < table.Count; i++)
                {
                    lb.Items.Add($"({i}){table[i].ToString()}");
                    
                }
            }

            //保存为txt文件
            public void saveToTXT(string path)
            {
                StreamWriter sw = new StreamWriter(path);

                for(int i = 0;i < table.Count; i++)
                {
                    sw.WriteLine($"({i}) {table[i].ToString()}");
                }
                sw.Close();
            }
        }

        //标识符列表
        private class identifierTable
        {
            public List<triple> table = new List<triple>();

            public identifierTable()
            {
                this.table.Clear();
            }

            public triple getIdentifierByName(string name)
            {
                foreach(triple t in table)
                {
                    if(t.name == name) return t;
                }
                return null;
            }



            public bool Add(string name)
            {
                if(getIdentifierByName(name)!= null)
                {
                    return false;
                }
                this.table.Add(new triple(name));
                return true;
            }


            public bool UpdateTypeByName(string name,string type)
            {
                triple temp = getIdentifierByName(name);

                if(temp ==  null) return false;

                if(temp.type != "") {
                    return false; 
                }
                temp.type = type;

                return true; 
                
            }
            public bool UpdateValueByName(string name, string value)
            {
                triple temp = getIdentifierByName(name);
                
                if(temp == null) return false; //优先判断是否存在这个temp

                temp.value = value;

                //if(temp.value ==  null) return false;

                return true;
            }
            
            public void dump(ListBox lb)
            {
                // lb.Items.Add($"|type| \t value| \t name|");
               
                lb.Items.Add($"============== 编译器，启动！==============");
                
                lb.Items.Add($"标识符列表如下：");
                lb.Items.Add($"|{"Name",-10}|{"Type",-10}|{"Value",-10}");
                foreach (triple t in table)
                {
                    lb.Items.Add($"|{t.ToString()}");
                }
            }
        }


        //临时变量表
        public class tempVariableTable
        {
            public List<triple> table = new List<triple>();

            public tempVariableTable()
            {
                this.table.Clear();
            }

            public triple createNewVariable()
            {
                //T0,T1,T2
                int count = table.Count;
                triple temp = new triple($"T{table.Count}");
                table.Add(temp);
                return temp;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

       
    }

    #endregion


}
